לעיתים אנו רוצים להפעיל קוד או פונקציה כלשהי פעם אחת בלבד בפניה (request) הבאה לאתר, אך אנו גם רוצים לשמור על יעילות הקוד ולכן לא נרצה לבצע בדיקה עבור כל בקשה לראות אם יש לנו פעולות מחכות לביצוע. בדיוק בשביל זה בניתי מחלקה שנקראת Session Executor המאפשרת בעזרת הסשן לפתור את הבעיה.
אז מתי נתקלים בכלל במקרים כאלו ?
נניח והמשתמש עשה פעולה כלשהי, אך אתם רוצים שהפעולה עצמה תתבצע רק כאשר המשתמש טוען את הדף בפעם הבאה (כל דף באתר). במקרה רגיל הייתם שומרים את הפעולה בסשן או בבסיס הנתונים ובודקים האם מחכות לכם פעולות בכל בקשה, ואם כן הייתם מבצעים אותן ומוחקים. הבעיה כמו שתואר היא הצורך בבדיקה עבור כל בקשה, למרות שהפעולה יכולה להיות דבר די נדיר.
אז מה Session Executor עושה ?
כאשר אנו מפעילים את המחלקה היא דבר ראשון רושמת את עצמה לסשן. כאשר אובייקטים ומחלקות נרשמים לסשן הם בעצם עוברים serialize ונשמרים בצורת מחרוזת. כעת בפנייה הבאה לדף כאשר הסשן פועל מחדש באמצעות הפקודה ()session_start הוא בעצם עובר אובייקט אובייקט ויוצר אותו מחדש (עם הנתונים שנשמרו בתוכו כמובן). יצירה של אובייקט נעשית ע"י הפעולה ההפוכה לשמירה שלו unserialize ובשלב זה אנו מפעילים את הקוד הרצוי.
לאחר שהקוד הרצוי פעל, אנו מבצעים סוג של "טריק" ומשנים את פונקציית ה- serialize שלא תחזיר דבר, מה שיגרום לאובייקט לא להישמר בסשן ולא להיות זמין בטעינת הדף הבאה - מה שרצינו!
להמשך הכתבה מאתר i-Dev לחץ כאן
תגובות לכתבה:
במילים שלי:
המחלקה מאפשרת לרשום פונקציה כלשהי לביצוע ככה שהיא תקרה בבקשה הבאה אל האתר - פעם אחת בלבד.
למשל אם יש לנו עמוד הזדהות שבסיומו נרצה שבבקשה הבאה יוצג למשתמש המשפט "מזמן לא ביקרת".
אנחנו רוצים שההודעה תופיע רק פעם אחת בבקשה הבאה אחרי ההזדהות (ולא תקרה בבקשה השלישית והלאה).
כלומר המשתמש נכנס לאתר וטוען עמוד = בקשה ראשונה.
לוחץ f5 = בקשה שניה.
עוד f5 = בקשה שלישית וכו'.
אם אנחנו רוצים שקוד כלשהו התבצעה רק בבקשה מספר שתיים, נוכל בסוף בקשה מס' 1 לרשום פעולה כלשהי לביצוע בבקשה הבאה.
שיפור קטן לקוד שעשיתי מאפשר לרשום כמה פעולות שונות (ולהגדיר אותם מחוץ למחלקה)
http://pastebin.com/nARfWDDQ
יש שני חסרונות לדרך הזו:
א. לא ניתן לרשום פונקציות אנונימיות והפונקציה שתרצו להפעיל בבקשה הבאה חייבת להיות מוגדרת לפני כן.
כלומר אם אתם רוצים להפעיל את הפונקציה greeting, הקוד חייב להכיר אותה בבקשה הבאה, כלומר לעשות include לקובץ שמכיל את ההגדרה שלה. אני הייתי ממליץ ליצור מחלקה עם פונקציות כאלה
ולהוסיף אותה ל autoload
ב. בגלל שהאובייקט נשמר בסשן, אחרי שמשתמשים בו הרשומה בסשן נשארת בכל זאת.
יותר מדי זבל בסשן. בתור אפשרות אפשר לנקות את הסשן מזבל בעת יצירת אובייקט חדש.
עוד על autoload וטעינת סקריפטים אוטומטית בעת הצורך אפשר לקרוא כאן
http://phpguide.co.il/טעינת סקריפטים לפי דרישה autoload.htm